package com.heima.lock.collection;

import java.util.HashMap;

/**
 *
 *  核心变量含义：
 *      Node<K,V>[] table ： 底层用来存储数据的数组
 *      int threshold：数组的扩容阈值，计算方式：数组容量 * 加载因子
 *                    ： 当集合中存储的元素个数 > threshold,则会触发数组的扩容
 *
 *  1. HashMap添加元素过程
 *      1. 计算key的hash值，并对hash值进行二次哈希(h = key.hashCode()) ^ (h >>> 16)，
 *          这样做是为了保障数据在数组中尽可能的散列分布。
 *      2. 根据hash值来计算应存入的索引位置：i = (n - 1) & hash
 *      3. 判断当前索引位置是否为null，为null则直接构建Node节点存入数组table对应的索引位置即可
 *      4. 如果当前索引位置不为null，会判断当前索引位置的元素是不是TreeNode，如果是则挂载到红黑树节点中
 *      5. 如果不是TreeNode，则会向下进行链表的挂载，在挂载链表时，会判断当前链表长度，如果长度  > 8，则会调用treeifyBin()--> replacementTreeNode()方法进行链表转红黑树结构
 *
 *  2. HashMap扩容机制
 *      2.1 刚创建的集合初始长度为0，并对加载因子：loadFactor赋值为0.75                 -- 泊松分布
 *      2.2 在第一次添加时，底层调用resize()方法对数组table进行扩容，扩容成一个长度为16的数组容器
 *      2.3 后续扩容时，是将数组长度 * 2
 *
 *  3. HashMap底层数据结构的转换
 *      1. 什么时候链表转红黑树？
 *          -- a. 数组长度 >= 64
 *          -- b. 链表长度 > 8
 *
 *      2. 红黑树什么时候转链表？
 *          -- a. 底层进行resize()扩容时，会导致数据重排列，可能导致红黑树的规模缩减，如果红黑树节点个数 <= 6,
 *              则会调用unTreeifyBin()--> replacementNode()方法将红黑树转为链表
 *         -- b. 在进行remove()删除集合元素时，底层会先判断当前红黑树节点情况，如果存在以下情况之一，则也会导致红黑树退化为链表：
 *               1. 根节点为null    2. 根节点的左子节点为null   3. 根节点的左孙子节点为null   4. 根节点的右子节点为null
 */

public class HashMapDemo1 {
    public static void main(String[] args) {
        HashMap<Student,String> map = new HashMap<>();
        for (int i = 1; i <= 11; i++) {
            map.put(new Student(),"world"+ i);
        }
        map.remove("");

        System.out.println("map = " + map);
    }
}
